package com.sap.jcp.sm.web;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionSupport;
import com.sap.jcp.sm.dao.UserDAO;
import com.sap.jcp.sm.dao.UserDAOImpl;
import com.sap.jcp.sm.dao.ConfigDAO;
import com.sap.jcp.sm.dao.ConfigDAOImpl;
import com.sap.jcp.sm.dao.UserTimelineDAO;
import com.sap.jcp.sm.dao.UserTimelineDAOImpl;
import com.sap.jcp.sm.domain.Config;
import com.sap.jcp.sm.domain.Shift;
import com.sap.jcp.sm.domain.Track;
import com.sap.jcp.sm.domain.User;
import com.sap.jcp.sm.domain.UserTimeline;
import com.sap.jcp.sm.dto.UserTimelineDTO;
import com.sap.jcp.sm.util.DateUtil;
import com.sap.jcp.sm.util.MappingUtil;
import com.sap.jcp.sm.util.TimelineUtil;

public class UserTimelineAction extends ActionSupport implements SessionAware, RequestAware {

	Map sessionMap;
	Map request;
	private static final long serialVersionUID = 1L;
	private UserTimelineDAO userTimelineDAO = new UserTimelineDAOImpl();
	private UserDAO userDAO = new UserDAOImpl();
	private ConfigDAO configDAO = new ConfigDAOImpl();
	private String message;
	private String weekId;
	private String dayIndex0;
	private String dayIndex1;
	private String dayIndex2;
	private String dayIndex3;
	private String dayIndex4;
	private String dayIndex5;
	private String dayIndex6;
	
	private String timeLineId0;
	private String timeLineId1;
	private String timeLineId2;
	private String timeLineId3;
	private String timeLineId4;
	private String timeLineId5;
	private String timeLineId6;
	
	private String user;
	private String track;
	private String shift;
	private String scheduleId;
	

	public String getScheduleId() {
		return scheduleId;
	}
	public void setScheduleId(String scheduleId) {
		this.scheduleId = scheduleId;
	}
	public void validate() {
		if (user == null || user.length() < 1) {
			super.addActionError("Invalid user");
		}
		if (track == null || track.length() < 1) {
			super.addActionError("Invalid Track");
		}
		if (shift == null || shift.length() < 1) {
			super.addActionError("Invalid Shift");
		}
	}
	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public String getTrack() {
		return track;
	}

	public void setTrack(String track) {
		this.track = track;
	}

	public String getShift() {
		return shift;
	}

	public void setShift(String shift) {
		this.shift = shift;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public UserTimelineDTO getSessionUserTimelineDTO () {
		UserTimelineDTO userTimelineDTO = (UserTimelineDTO) sessionMap.get("userTimelineDTO");
		if (userTimelineDTO == null) {
			userTimelineDTO = new UserTimelineDTO();
		}
		return userTimelineDTO;
	}
	
	public String loadAction() {
		String weekId = (String) request.get("weekId");
		loadUserTimeLineToSession(weekId);
		return SUCCESS;
	}

	private void loadUserTimeLineToSession(String weekId) {
		List<UserTimeline> userTimelineList = userTimelineDAO.listUserTimeline(weekId);
		Map<String, UserTimeline> userTimelineMap = MappingUtil.userTimelineMapper(userTimelineList);
		Map<String, User> userList = (Map<String, User>) sessionMap.get("approvedUsers");
		UserTimelineDTO  userTimelineDTO = getSessionUserTimelineDTO();
		String currentDateString = DateUtil.getWeekCode(new Date());
		userTimelineDTO.setWeekId(currentDateString);
		userTimelineDTO.setCurrentWeekId(weekId);
		userTimelineDTO.setNextWeekId(DateUtil.getNextWeekId(weekId));
		userTimelineDTO.setPreviousWeekId(DateUtil.getPreviousWeekId(weekId));
		Config config = configDAO.list();
		userTimelineDTO = new TimelineUtil().createUserTimelineDTO(
				userTimelineMap, userList, weekId, userTimelineDTO, (Map<String, Shift>) sessionMap
						.get("shift"), (Map<String, Track>) sessionMap.get("track"),config);
		sessionMap.put("userTimelineDTO", userTimelineDTO);
	}
	
	
	@Override
	public void setSession(Map<String, Object> map) {
		this.sessionMap = map;
	}
	public String getWeekId() {
		return weekId;
	}

	public void setWeekId(String weekId) {
		this.weekId = weekId;
	}

	public Map<String, Object> getSession() {
		 return sessionMap;
	}

	@Override
	public void setRequest(Map<String, Object> arg0) {
		this.request = arg0;
		
	}
	
	public String manageSchedle() {
		int index = 0;
		if (getActionErrors() != null && !getActionErrors().isEmpty()) {
			return ERROR;
		}
		UserTimeline userTimeline = null;
		for (String day : getWeekDayList()) {
			userTimeline = new UserTimeline();
			if (day != null) {
				String currentDate = getNextCurrentDate(weekId, index);
				userTimeline.setWeek(weekId);
				userTimeline.setShift(shift);
				userTimeline.setTrack(track);
				userTimeline.setUser(user);
				String date[] = currentDate.split("-"); 
				userTimeline.setYear(date[2]);
				userTimeline.setDay(date[0]);
				userTimeline.setMonth(date[1]);
				String timeLineShiftId = getUserTimeLineIds().get(index);
				String []timeLineShift = timeLineShiftId.split("#");
				
				userTimeline.setUserTimelineId(date[0] + date[1] + date[2] + user);
				if (timeLineShift != null && timeLineShift.length > 0 && !StringUtils.isEmpty(timeLineShift[0])) {
					userTimeline.setUserTimelineId(timeLineShift[0]);
					userTimelineDAO.updateTimeLine(userTimeline);
					try {
						manageCompOffShiftCount(user , timeLineShift[1], date[0] + "-" + date[1] + "-" + date[2], false);
					} catch (Exception e) {
						e.printStackTrace();
					}
				} else {
					userTimelineDAO.saveTimeLine(userTimeline);
				}
				try {
					manageCompOffShiftCount(user, shift, date[0] + "-" + date[1] + "-" + date[2], true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			index++;
		}
		loadUserTimeLineToSession(weekId);
		return SUCCESS;
	}
	
	private void manageCompOffShiftCount(String userId, String shiftId, String weekId, boolean isAdd) {
		Map<String, User> userMap = (Map<String, User>) sessionMap.get("approvedUsers");
		Map<String, Shift> shiftMap = (Map<String, Shift>) sessionMap.get("shift");
		Shift shiftDetails = shiftMap.get(shiftId);
		User userDetails = userMap.get(userId);
		if ("Vacation".equalsIgnoreCase(shiftDetails.getShiftName())) {
			return;
		}
		if (isAdd) {
			if ("Comp Off".equalsIgnoreCase(shiftDetails.getShiftName())) {
				int compCount = Integer.parseInt(userDetails.getCompOffCount());
				compCount-=1;
				userDetails.setCompOffCount("" + compCount);
			} else if (DateUtil.isWeekEnd(weekId)) {
				if (shiftDetails.getIsCompOffApplicable()!= null && "Yes".equalsIgnoreCase(shiftDetails.getIsCompOffApplicable())){
					int compCount = Integer.parseInt(userDetails.getCompOffCount());
					compCount+=1;
					userDetails.setCompOffCount("" + compCount);
				}
				if (shiftDetails.getIsScheduleApplicable()!= null && "Yes".equalsIgnoreCase(shiftDetails.getIsScheduleApplicable())){
					int shiftCount = Integer.parseInt(userDetails.getShiftCount());
					shiftCount+=1;
					userDetails.setShiftCount("" + shiftCount);
				}
				
			} else {
				if (shiftDetails.getIsScheduleApplicable()!= null && "Yes".equalsIgnoreCase(shiftDetails.getIsScheduleApplicable())){
					int shiftCount = Integer.parseInt(userDetails.getShiftCount());
					shiftCount+=1;
					userDetails.setShiftCount("" + shiftCount);
				}
			}
		} else {
			if ("Comp Off".equalsIgnoreCase(shiftDetails.getShiftName())) {
				int compCount = Integer.parseInt(userDetails.getCompOffCount());
				compCount+=1;
				userDetails.setCompOffCount("" + compCount);
			} else if (DateUtil.isWeekEnd(weekId)) {
				if (shiftDetails.getIsCompOffApplicable()!= null && "Yes".equalsIgnoreCase(shiftDetails.getIsCompOffApplicable())){
					int compCount = Integer.parseInt(userDetails.getCompOffCount());
					compCount-=1;
					userDetails.setCompOffCount("" + compCount);
				}
				if (shiftDetails.getIsScheduleApplicable()!= null && "Yes".equalsIgnoreCase(shiftDetails.getIsScheduleApplicable())){
					int shiftCount = Integer.parseInt(userDetails.getShiftCount());
					shiftCount-=1;
					userDetails.setShiftCount("" + shiftCount);
				}
			} else {
				if (shiftDetails.getIsScheduleApplicable()!= null && "Yes".equalsIgnoreCase(shiftDetails.getIsScheduleApplicable())){
					int shiftCount = Integer.parseInt(userDetails.getShiftCount());
					shiftCount-=1;
					userDetails.setShiftCount("" + shiftCount);
				}
			}
		}
		/*List<User> approvedUserList = userDAO.pendingListUser("Approved");
		sessionMap.put("approvedUsers", MappingUtil.convertUserListToMap(approvedUserList));*/
		userDAO.updateUser(userDetails);
	}
	
	public String deleteSchedule() {
		UserTimeline userTimelineDetails = userTimelineDAO.getTimeLine(scheduleId);
		try {
			manageCompOffShiftCount(userTimelineDetails.getUser(),
					userTimelineDetails.getShift(), userTimelineDetails
							.getDay()
							+ "-"
							+ userTimelineDetails.getMonth()
							+ "-"
							+ userTimelineDetails.getYear(), false);
		} catch (Exception e) {
			e.printStackTrace();
		}
		userTimelineDAO.deleteSchedule(userTimelineDetails);
		loadUserTimeLineToSession(weekId);
		return SUCCESS;
		
	}
	
	public String getNextCurrentDate(String currentWeekId, int index) {
		
		SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
		String currentDate = "";
		try {
			Date currentWeekDate = sdf.parse(currentWeekId);
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(currentWeekDate);
			calendar.add(Calendar.DATE, index);
			Date nextWeekDate = calendar.getTime();
			currentDate = sdf.format(nextWeekDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return currentDate;
			
	}

	private List<String> getWeekDayList() {
		List<String> weekDayList = new ArrayList<String>();
		weekDayList.add(dayIndex0);
		weekDayList.add(dayIndex1);
		weekDayList.add(dayIndex2);
		weekDayList.add(dayIndex3);
		weekDayList.add(dayIndex4);
		weekDayList.add(dayIndex5);
		weekDayList.add(dayIndex6);
		return weekDayList;
	}

	private List<String> getUserTimeLineIds() {
		List<String> UserTimeLineIdList = new ArrayList<String>();
		UserTimeLineIdList.add(timeLineId0);
		UserTimeLineIdList.add(timeLineId1);
		UserTimeLineIdList.add(timeLineId2);
		UserTimeLineIdList.add(timeLineId3);
		UserTimeLineIdList.add(timeLineId4);
		UserTimeLineIdList.add(timeLineId5);
		UserTimeLineIdList.add(timeLineId6);
		return UserTimeLineIdList;
	}

	public String getDayIndex0() {
		return dayIndex0;
	}

	public void setDayIndex0(String dayIndex0) {
		this.dayIndex0 = dayIndex0;
	}

	public String getDayIndex1() {
		return dayIndex1;
	}

	public void setDayIndex1(String dayIndex1) {
		this.dayIndex1 = dayIndex1;
	}

	public String getDayIndex2() {
		return dayIndex2;
	}

	public void setDayIndex2(String dayIndex2) {
		this.dayIndex2 = dayIndex2;
	}

	public String getDayIndex3() {
		return dayIndex3;
	}

	public void setDayIndex3(String dayIndex3) {
		this.dayIndex3 = dayIndex3;
	}

	public String getDayIndex4() {
		return dayIndex4;
	}

	public void setDayIndex4(String dayIndex4) {
		this.dayIndex4 = dayIndex4;
	}

	public String getDayIndex5() {
		return dayIndex5;
	}

	public void setDayIndex5(String dayIndex5) {
		this.dayIndex5 = dayIndex5;
	}

	public String getDayIndex6() {
		return dayIndex6;
	}

	public void setDayIndex6(String dayIndex6) {
		this.dayIndex6 = dayIndex6;
	}
	
	
	public String getTimeLineId1() {
		return timeLineId1;
	}

	public void setTimeLineId1(String timeLineId1) {
		this.timeLineId1 = timeLineId1;
	}

	public String getTimeLineId2() {
		return timeLineId2;
	}

	public void setTimeLineId2(String timeLineId2) {
		this.timeLineId2 = timeLineId2;
	}

	public String getTimeLineId3() {
		return timeLineId3;
	}

	public void setTimeLineId3(String timeLineId3) {
		this.timeLineId3 = timeLineId3;
	}

	public String getTimeLineId4() {
		return timeLineId4;
	}

	public void setTimeLineId4(String timeLineId4) {
		this.timeLineId4 = timeLineId4;
	}

	public String getTimeLineId5() {
		return timeLineId5;
	}

	public void setTimeLineId5(String timeLineId5) {
		this.timeLineId5 = timeLineId5;
	}

	public String getTimeLineId6() {
		return timeLineId6;
	}

	public void setTimeLineId6(String timeLineId6) {
		this.timeLineId6 = timeLineId6;
	}

	public String getTimeLineId0() {
		return timeLineId0;
	}

	public void setTimeLineId0(String timeLineId0) {
		this.timeLineId0 = timeLineId0;
	}
}
